From 3d0d5682f3ced01ce5e1527087879102af06eb77 Mon Sep 17 00:00:00 2001 From: "kaf24@labyrinth.cl.cam.ac.uk" Date: Wed, 19 Feb 2003 17:26:26 +0000 Subject: [PATCH] bitkeeper revision 1.68 (3e53be42OUDyPzjPoKWKLkNgVODyHA) Many files: Big changes to blkdev layer -- rings now allocated in hypervisor space. --- xen-2.4.16/common/domain.c | 27 ++- xen-2.4.16/common/event.c | 2 - xen-2.4.16/drivers/block/xen_block.c | 171 +++++++----------- xen-2.4.16/include/hypervisor-ifs/block.h | 53 +++--- .../include/hypervisor-ifs/hypervisor-if.h | 34 ++-- xen-2.4.16/include/hypervisor-ifs/network.h | 5 +- xen-2.4.16/include/xeno/sched.h | 4 +- .../arch/xeno/drivers/block/xl_block.c | 113 ++++-------- .../arch/xeno/drivers/block/xl_block_test.c | 2 +- xenolinux-2.4.16-sparse/arch/xeno/mm/init.c | 61 ++++++- .../include/asm-xeno/pgtable.h | 3 +- 11 files changed, 225 insertions(+), 250 deletions(-) diff --git a/xen-2.4.16/common/domain.c b/xen-2.4.16/common/domain.c index 9e5f3dd8b8..4a9a8a8359 100644 --- a/xen-2.4.16/common/domain.c +++ b/xen-2.4.16/common/domain.c @@ -42,10 +42,17 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu) p->domain = dom_id; p->processor = cpu; + spin_lock_init(&p->blk_ring_lock); + p->shared_info = (void *)get_free_page(GFP_KERNEL); memset(p->shared_info, 0, PAGE_SIZE); SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), dom_id); + if ( sizeof(*p->blk_ring_base) > PAGE_SIZE ) BUG(); + p->blk_ring_base = (blk_ring_t *)get_free_page(GFP_KERNEL); + memset(p->blk_ring_base, 0, PAGE_SIZE); + SHARE_PFN_WITH_DOMAIN(virt_to_page(p->blk_ring_base), dom_id); + SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES); SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS); @@ -54,16 +61,7 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu) p->active_mm = &p->mm; p->num_net_vifs = 0; - INIT_LIST_HEAD(&p->io_done_queue); - spin_lock_init(&p->io_done_queue_lock); - - /* - * KAF: Passing in newdomain struct to this function is gross! - * Therefore, for now we just allocate the single blk_ring - * before the multiople net_rings :-) - */ - p->blk_ring_base = (blk_ring_t *)(p->shared_info + 1); - p->net_ring_base = (net_ring_t *)(p->blk_ring_base + 1); + p->net_ring_base = (net_ring_t *)(p->shared_info + 1); INIT_LIST_HEAD(&p->pg_head); p->tot_pages = 0; write_lock_irqsave(&tasklist_lock, flags); @@ -218,6 +216,9 @@ void release_task(struct task_struct *p) } if ( p->mm.perdomain_pt ) free_page((unsigned long)p->mm.perdomain_pt); + UNSHARE_PFN(virt_to_page(p->blk_ring_base)); + free_page((unsigned long)p->blk_ring_base); + UNSHARE_PFN(virt_to_page(p->shared_info)); free_page((unsigned long)p->shared_info); @@ -316,7 +317,7 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) virt_startinfo_addr->num_net_rings = p->num_net_vifs; /* Add block io interface */ - virt_startinfo_addr->blk_ring = (blk_ring_t *)SH2G(p->blk_ring_base); + virt_startinfo_addr->blk_ring = virt_to_phys(p->blk_ring_base); /* Copy the command line */ strcpy(virt_startinfo_addr->cmd_line, meminfo->cmd_line); @@ -548,9 +549,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params) virt_startinfo_address->num_net_rings = p->num_net_vifs; /* Add block io interface */ - virt_startinfo_address->blk_ring = - (blk_ring_t *)SHIP2GUEST(p->blk_ring_base); - + virt_startinfo_address->blk_ring = virt_to_phys(p->blk_ring_base); /* We tell OS about any modules we were given. */ if ( nr_mods > 1 ) diff --git a/xen-2.4.16/common/event.c b/xen-2.4.16/common/event.c index 4cc2c70287..2774806443 100644 --- a/xen-2.4.16/common/event.c +++ b/xen-2.4.16/common/event.c @@ -14,7 +14,6 @@ typedef void (*hyp_event_callback_fn_t)(void); extern void schedule(void); -extern void flush_blk_queue(void); extern void update_shared_ring(void); /* Ordering must match definitions of _HYP_EVENT_* in xeno/sched.h */ @@ -23,7 +22,6 @@ static hyp_event_callback_fn_t event_call_fn[] = schedule, update_shared_ring, kill_domain, - flush_blk_queue }; /* Handle outstanding events for the currently-executing domain. */ diff --git a/xen-2.4.16/drivers/block/xen_block.c b/xen-2.4.16/drivers/block/xen_block.c index fa3833d03a..8e70eff572 100644 --- a/xen-2.4.16/drivers/block/xen_block.c +++ b/xen-2.4.16/drivers/block/xen_block.c @@ -34,12 +34,12 @@ typedef struct blk_request { struct list_head queue; struct buffer_head *bh; - blk_ring_entry_t request; - struct task_struct *domain; /* requesting domain */ + blk_ring_req_entry_t *request; + struct task_struct *domain; /* requesting domain */ } blk_request_t; #define MAX_PENDING_REQS 256 /* very arbitrary */ static kmem_cache_t *blk_request_cachep; -static atomic_t nr_pending, nr_done; +static atomic_t nr_pending; static int pending_work; /* which domains have work for us? */ @@ -62,10 +62,12 @@ int dispatch_debug_block_io (int index); void end_block_io_op(struct buffer_head * bh) { unsigned long cpu_mask; - /* struct list_head *list;*/ blk_request_t *blk_request = NULL; - unsigned long flags; /* irq save */ + unsigned long flags; struct task_struct *p; + int position = 0; + blk_ring_t *blk_ring; + int loop; if (XEN_BLK_DEBUG) printk(XEN_BLK_DEBUG_LEVEL "XEN end_block_io_op, bh: %lx\n", @@ -77,76 +79,24 @@ void end_block_io_op(struct buffer_head * bh) p = blk_request->domain; - atomic_inc(&nr_done); - spin_lock_irqsave(&p->io_done_queue_lock, flags); - list_add_tail(&blk_request->queue, &p->io_done_queue); - /* enqueue work for 'flush_blk_queue' handler */ - cpu_mask = mark_hyp_event(p, _HYP_EVENT_BLK_RX); - spin_unlock_irqrestore(&p->io_done_queue_lock, flags); - - /* now kick the hypervisor */ - hyp_event_notify(cpu_mask); - return; - - bad_interrupt: - printk (KERN_ALERT - " block io interrupt received for unknown buffer [0x%lx]\n", - (unsigned long) bh); - BUG(); - return; -} - -/* - * flush_blk_queue - * - * Called by the hypervisor synchronously when there is something to do - * (block transfers have completed) - */ - -void flush_blk_queue(void) -{ - struct task_struct *p = current; - blk_request_t *blk_request; - int position = 0; - blk_ring_t *blk_ring; - unsigned long flags; - int loop; + /* Place on the response ring for the relevant domain. */ + spin_lock_irqsave(&p->blk_ring_lock, flags); + blk_ring = p->blk_ring_base; + position = blk_ring->resp_prod; + blk_ring->resp_ring[position].id = blk_request->request->id; + blk_ring->resp_ring[position].status = 0; + blk_ring->resp_prod = BLK_RESP_RING_INC(blk_ring->resp_prod); + spin_unlock_irqrestore(&p->blk_ring_lock, flags); - spin_lock_irqsave(&p->io_done_queue_lock, flags); - clear_bit(_HYP_EVENT_BLK_RX, &p->hyp_events); + /* Kick the relevant domain. */ + cpu_mask = mark_guest_event(p, _EVENT_BLK_RESP); + guest_event_notify(cpu_mask); + + /* Free state associated with this request. */ + if ( blk_request->bh ) + kfree(blk_request->bh); + kmem_cache_free(blk_request_cachep, blk_request); - while ( !list_empty(&p->io_done_queue) ) - { - blk_request = list_entry(p->io_done_queue.next, blk_request_t, queue); - list_del(&blk_request->queue); - spin_unlock_irqrestore(&p->io_done_queue_lock, flags); - atomic_dec(&nr_done); - - /* place on ring for guest os */ - blk_ring = p->blk_ring_base; - position = blk_ring->brx_prod; - - if (XEN_BLK_DEBUG) - printk(XEN_BLK_DEBUG_LEVEL "XEN flush_blk_queue [%d]\n", position); - - memcpy(&blk_ring->brx_ring[position], &blk_request->request, - sizeof(blk_ring_entry_t)); - blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod); - - /* notify appropriate guest os */ - set_bit(_EVENT_BLK_RX, &p->shared_info->events); - - /* free the buffer header allocated in do_block_io_op */ - if ( blk_request->bh ) - kfree(blk_request->bh); - - kmem_cache_free(blk_request_cachep, blk_request); - - spin_lock_irqsave(&p->io_done_queue_lock, flags); - } - spin_unlock_irqrestore(&p->io_done_queue_lock, flags); - - /* XXX SMH: below is ugly and dangerous -- fix */ /* * now check if there is any pending work from any domain @@ -177,7 +127,14 @@ void flush_blk_queue(void) } } - return; + return; + + bad_interrupt: + printk (KERN_ALERT + " block io interrupt received for unknown buffer [0x%lx]\n", + (unsigned long) bh); + BUG(); + return; } @@ -206,15 +163,15 @@ long do_block_io_op_domain (struct task_struct* task) if (XEN_BLK_DEBUG) printk(XEN_BLK_DEBUG_LEVEL "XEN do_block_io_op %d %d\n", - blk_ring->btx_cons, blk_ring->btx_prod); - - for (loop = blk_ring->btx_cons; - loop != blk_ring->btx_prod; - loop = BLK_TX_RING_INC(loop)) { + blk_ring->req_cons, blk_ring->req_prod); + for ( loop = blk_ring->req_cons; + loop != blk_ring->req_prod; + loop = BLK_REQ_RING_INC(loop) ) + { status = 1; - switch (blk_ring->btx_ring[loop].operation) { + switch (blk_ring->req_ring[loop].operation) { case XEN_BLOCK_READ: case XEN_BLOCK_WRITE: @@ -231,7 +188,7 @@ long do_block_io_op_domain (struct task_struct* task) default: printk (KERN_ALERT "error: unknown block io operation [%d]\n", - blk_ring->btx_ring[loop].operation); + blk_ring->req_ring[loop].operation); BUG(); } @@ -247,7 +204,7 @@ long do_block_io_op_domain (struct task_struct* task) } } - blk_ring->btx_cons = loop; + blk_ring->req_cons = loop; return 0L; } @@ -265,14 +222,13 @@ int dispatch_probe_block_io (int index) blk_ring_t *blk_ring = current->blk_ring_base; xen_disk_info_t *xdi; - xdi = phys_to_virt((unsigned long)blk_ring->btx_ring[index].buffer); + xdi = phys_to_virt((unsigned long)blk_ring->req_ring[index].buffer); ide_probe_devices(xdi); - - memcpy(&blk_ring->brx_ring[blk_ring->brx_prod], - &blk_ring->btx_ring[index], - sizeof(blk_ring_entry_t)); - blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod); + + blk_ring->resp_ring[blk_ring->resp_prod].id = blk_ring->req_ring[index].id; + blk_ring->resp_ring[blk_ring->resp_prod].status = 0; + blk_ring->resp_prod = BLK_RESP_RING_INC(blk_ring->resp_prod); return 0; } @@ -291,24 +247,24 @@ int dispatch_rw_block_io (int index) * check to make sure that the block request seems at least * a bit legitimate */ - if ((blk_ring->btx_ring[index].block_size & (0x200 - 1)) != 0) { + if ((blk_ring->req_ring[index].block_size & (0x200 - 1)) != 0) { printk(KERN_ALERT " error: dodgy block size: %d\n", - blk_ring->btx_ring[index].block_size); + blk_ring->req_ring[index].block_size); BUG(); } - if(blk_ring->btx_ring[index].buffer == NULL) { + if(blk_ring->req_ring[index].buffer == NULL) { printk(KERN_ALERT "xen_block: bogus buffer from guestOS\n"); BUG(); } if (XEN_BLK_DEBUG) { - printk(XEN_BLK_DEBUG_LEVEL " btx_cons: %d btx_prod %d index: %d " - "op: %s, pri: %s\n", blk_ring->btx_cons, blk_ring->btx_prod, + printk(XEN_BLK_DEBUG_LEVEL " req_cons: %d req_prod %d index: %d " + "op: %s, pri: %s\n", blk_ring->req_cons, blk_ring->req_prod, index, - (blk_ring->btx_ring[index].operation == XEN_BLOCK_READ ? + (blk_ring->req_ring[index].operation == XEN_BLOCK_READ ? "read" : "write"), - (blk_ring->btx_ring[index].priority == XEN_BLOCK_SYNC ? + (blk_ring->req_ring[index].priority == XEN_BLOCK_SYNC ? "sync" : "async")); } @@ -319,7 +275,6 @@ int dispatch_rw_block_io (int index) blk_request = kmem_cache_alloc(blk_request_cachep, GFP_ATOMIC); /* we'll be doing this frequently, would a cache be appropriate? */ - /* free in flush_blk_queue */ bh = (struct buffer_head *) kmalloc(sizeof(struct buffer_head), GFP_KERNEL); if (!bh) { @@ -330,16 +285,16 @@ int dispatch_rw_block_io (int index) /* set just the important bits of the buffer header */ memset (bh, 0, sizeof (struct buffer_head)); - bh->b_blocknr = blk_ring->btx_ring[index].block_number; - bh->b_size = blk_ring->btx_ring[index].block_size; - bh->b_dev = blk_ring->btx_ring[index].device; - bh->b_rsector = blk_ring->btx_ring[index].sector_number; + bh->b_blocknr = blk_ring->req_ring[index].block_number; + bh->b_size = blk_ring->req_ring[index].block_size; + bh->b_dev = blk_ring->req_ring[index].device; + bh->b_rsector = blk_ring->req_ring[index].sector_number; bh->b_data = phys_to_virt((unsigned long) - blk_ring->btx_ring[index].buffer); + blk_ring->req_ring[index].buffer); bh->b_count.counter = 1; bh->b_xen_request = (void *)blk_request; - if (blk_ring->btx_ring[index].operation == XEN_BLOCK_WRITE) { + if (blk_ring->req_ring[index].operation == XEN_BLOCK_WRITE) { bh->b_state = ((1 << BH_JBD) | (1 << BH_Mapped) | (1 << BH_Req) | (1 << BH_Dirty) | (1 << BH_Uptodate)); operation = WRITE; @@ -348,9 +303,8 @@ int dispatch_rw_block_io (int index) operation = READ; } - /* save meta data about request XXX SMH: should copy_from_user() */ - memcpy(&blk_request->request, - &blk_ring->btx_ring[index], sizeof(blk_ring_entry_t)); + /* save meta data about request */ + blk_request->request = &blk_ring->req_ring[index]; blk_request->bh = bh; blk_request->domain = current; @@ -400,9 +354,8 @@ void dump_queue_head(struct list_head *queue, char *name) static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs) { - printk("Dumping block queue stats:\n"); - printk("nr_pending = %d, nr_done = %d\n", - atomic_read(&nr_pending), atomic_read(&nr_done)); + printk("Dumping block queue stats: nr_pending = %d\n", + atomic_read(&nr_pending)); } @@ -422,6 +375,8 @@ void initialize_block_io () /* If bit i is true then domain i has work for us to do. */ pending_work = 0; + + atomic_set(&nr_pending, 0); } diff --git a/xen-2.4.16/include/hypervisor-ifs/block.h b/xen-2.4.16/include/hypervisor-ifs/block.h index 76db90da1a..1bf198e196 100644 --- a/xen-2.4.16/include/hypervisor-ifs/block.h +++ b/xen-2.4.16/include/hypervisor-ifs/block.h @@ -26,38 +26,41 @@ #define XEN_BLOCK_MAX_DOMAINS 32 /* NOTE: FIX THIS. VALUE SHOULD COME FROM? */ -#define BLK_TX_RING_SIZE 256 -#define BLK_RX_RING_SIZE 256 +#define BLK_REQ_RING_SIZE 64 +#define BLK_RESP_RING_SIZE 64 -#define BLK_TX_RING_MAX_ENTRIES (BLK_TX_RING_SIZE - 2) -#define BLK_RX_RING_MAX_ENTRIES (BLK_RX_RING_SIZE - 2) +#define BLK_REQ_RING_MAX_ENTRIES (BLK_REQ_RING_SIZE - 2) +#define BLK_RESP_RING_MAX_ENTRIES (BLK_RESP_RING_SIZE - 2) -#define BLK_TX_RING_INC(_i) (((_i)+1) & (BLK_TX_RING_SIZE-1)) -#define BLK_RX_RING_INC(_i) (((_i)+1) & (BLK_RX_RING_SIZE-1)) -#define BLK_TX_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_TX_RING_SIZE-1)) -#define BLK_RX_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_RX_RING_SIZE-1)) +#define BLK_REQ_RING_INC(_i) (((_i)+1) & (BLK_REQ_RING_SIZE-1)) +#define BLK_RESP_RING_INC(_i) (((_i)+1) & (BLK_RESP_RING_SIZE-1)) +#define BLK_REQ_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_REQ_RING_SIZE-1)) +#define BLK_RESP_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_RESP_RING_SIZE-1)) -typedef struct blk_ring_entry +typedef struct blk_ring_req_entry { - void * id; /* for guest os use; used for the bh */ - int priority; /* orig sched pri, SYNC or ASYNC for now */ - int operation; /* XEN_BLOCK_READ or XEN_BLOCK_WRITE */ - char * buffer; - unsigned long block_number; /* block number */ - unsigned short block_size; /* block size */ - kdev_t device; - unsigned long sector_number; /* real buffer location on disk */ -} blk_ring_entry_t; + void * id; /* for guest os use */ + int priority; /* SYNC or ASYNC for now */ + int operation; /* XEN_BLOCK_READ or XEN_BLOCK_WRITE */ + char * buffer; + unsigned long block_number; /* block number */ + unsigned short block_size; /* block size */ + kdev_t device; + unsigned long sector_number; /* real buffer location on disk */ +} blk_ring_req_entry_t; + +typedef struct blk_ring_resp_entry +{ + void *id; + unsigned long status; +} blk_ring_resp_entry_t; typedef struct blk_ring_st { - blk_ring_entry_t *btx_ring; - unsigned int btx_prod, btx_cons; - unsigned int btx_ring_size; - - blk_ring_entry_t *brx_ring; - unsigned int brx_prod, brx_cons; - unsigned int brx_ring_size; + unsigned int req_prod, req_cons; + unsigned int resp_prod, resp_cons; + blk_ring_req_entry_t req_ring[BLK_REQ_RING_SIZE]; + blk_ring_resp_entry_t resp_ring[BLK_RESP_RING_SIZE]; } blk_ring_t; #define MAX_XEN_DISK_COUNT 100 diff --git a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h index cf3edb8cfb..6ecac5848e 100644 --- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h +++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h @@ -103,22 +103,20 @@ typedef struct */ /* Events that a guest OS may receive from the hypervisor. */ -#define EVENT_BLK_TX 0x01 /* packets for transmission. */ -#define EVENT_BLK_RX 0x02 /* empty buffers for receive. */ -#define EVENT_TIMER 0x04 /* a timeout has been updated. */ -#define EVENT_DIE 0x08 /* OS is about to be killed. Clean up please! */ -#define EVENT_DEBUG 0x10 /* request guest to dump debug info (gross!) */ -#define EVENT_NET_TX 0x20 /* packets for transmission. */ -#define EVENT_NET_RX 0x40 /* empty buffers for receive. */ +#define EVENT_BLK_RESP 0x01 /* A block device response has been queued. */ +#define EVENT_TIMER 0x02 /* A timeout has been updated. */ +#define EVENT_DIE 0x04 /* OS is about to be killed. Clean up please! */ +#define EVENT_DEBUG 0x08 /* Request guest to dump debug info (gross!) */ +#define EVENT_NET_TX 0x10 /* There are packets for transmission. */ +#define EVENT_NET_RX 0x20 /* There are empty buffers for receive. */ /* Bit offsets, as opposed to the above masks. */ -#define _EVENT_BLK_TX 0 -#define _EVENT_BLK_RX 1 -#define _EVENT_TIMER 2 -#define _EVENT_DIE 3 -#define _EVENT_NET_TX 4 -#define _EVENT_NET_RX 5 -#define _EVENT_DEBUG 6 +#define _EVENT_BLK_RESP 0 +#define _EVENT_TIMER 1 +#define _EVENT_DIE 2 +#define _EVENT_NET_TX 3 +#define _EVENT_NET_RX 4 +#define _EVENT_DEBUG 5 /* @@ -195,13 +193,13 @@ typedef struct shared_info_st { */ typedef struct start_info_st { unsigned long nr_pages; /* total pages allocated to this domain */ - shared_info_t *shared_info; /* start address of shared info struct */ + shared_info_t *shared_info; /* VIRTUAL address of shared info struct */ unsigned long pt_base; /* VIRTUAL address of page directory */ - unsigned long mod_start; /* start address of pre-loaded module */ + unsigned long mod_start; /* VIRTUAL address of pre-loaded module */ unsigned long mod_len; /* size (bytes) of pre-loaded module */ - net_ring_t *net_rings; + net_ring_t *net_rings; /* network rings (VIRTUAL ADDRESS) */ int num_net_rings; - blk_ring_t *blk_ring; /* block io communication rings */ + unsigned long blk_ring; /* block io ring (MACHINE ADDRESS) */ unsigned char cmd_line[1]; /* variable-length */ } start_info_t; diff --git a/xen-2.4.16/include/hypervisor-ifs/network.h b/xen-2.4.16/include/hypervisor-ifs/network.h index f3f13dc77b..6f528fcf63 100644 --- a/xen-2.4.16/include/hypervisor-ifs/network.h +++ b/xen-2.4.16/include/hypervisor-ifs/network.h @@ -39,7 +39,7 @@ typedef struct net_ring_st { */ tx_entry_t *tx_ring; unsigned int tx_prod, tx_cons, tx_event; - unsigned int tx_ring_size; + /* * Guest OS places empty buffers into ring at rx_prod. * Hypervisor fills buffers as rx_cons. @@ -50,11 +50,10 @@ typedef struct net_ring_st { */ rx_entry_t *rx_ring; unsigned int rx_prod, rx_cons, rx_event; - unsigned int rx_ring_size; } net_ring_t; /* Specify base of per-domain array. Get returned free slot in the array. */ -//net_ring_t *create_net_vif(int domain); +/*net_ring_t *create_net_vif(int domain);*/ /* Packet routing/filtering code follows: */ diff --git a/xen-2.4.16/include/xeno/sched.h b/xen-2.4.16/include/xeno/sched.h index ec65902fef..a02c28ff22 100644 --- a/xen-2.4.16/include/xeno/sched.h +++ b/xen-2.4.16/include/xeno/sched.h @@ -48,7 +48,6 @@ extern struct mm_struct init_mm; #define _HYP_EVENT_NEED_RESCHED 0 #define _HYP_EVENT_NET_RX 1 #define _HYP_EVENT_DIE 2 -#define _HYP_EVENT_BLK_RX 3 #define PF_DONEFPUINIT 0x1 /* Has the FPU been initialised for this task? */ #define PF_USEDFPU 0x2 /* Has this task used the FPU since last save? */ @@ -77,8 +76,7 @@ struct task_struct { /* Block I/O */ blk_ring_t *blk_ring_base; - struct list_head io_done_queue; - spinlock_t io_done_queue_lock; + spinlock_t blk_ring_lock; int has_cpu, policy, counter; diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c index f7bd088ff4..e9f1aed53c 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c @@ -40,8 +40,7 @@ static int xlblk_read_ahead; static int xlblk_hardsect_size[XLBLK_MAX]; static int xlblk_max_sectors[XLBLK_MAX]; -#define XLBLK_RX_IRQ _EVENT_BLK_RX -#define XLBLK_TX_IRQ _EVENT_BLK_TX +#define XLBLK_RESPONSE_IRQ _EVENT_BLK_RESP #define DEBUG_IRQ _EVENT_DEBUG @@ -56,6 +55,8 @@ xlblk_device_t xlblk_device; #define XLBLK_DEBUG 0 #define XLBLK_DEBUG_IOCTL 0 +static blk_ring_t *blk_ring; + /* * disk management */ @@ -203,7 +204,6 @@ void hypervisor_request(void * id, kdev_t device, int mode) { - blk_ring_t *blk_ring = start_info.blk_ring; int position; void *buffer_pa, *buffer_ma; kdev_t phys_device = (kdev_t) 0; @@ -246,24 +246,24 @@ void hypervisor_request(void * id, } - if (BLK_TX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons) { - printk (KERN_ALERT "hypervisor_request: btx_cons: %d, btx_prod:%d", - blk_ring->btx_cons, blk_ring->btx_prod); + if (BLK_REQ_RING_INC(blk_ring->req_prod) == blk_ring->req_cons) { + printk (KERN_ALERT "hypervisor_request: req_cons: %d, req_prod:%d", + blk_ring->req_cons, blk_ring->req_prod); BUG(); } /* Fill out a communications ring structure & trap to the hypervisor */ - position = blk_ring->btx_prod; - blk_ring->btx_ring[position].id = id; - blk_ring->btx_ring[position].priority = mode; - blk_ring->btx_ring[position].operation = operation; - blk_ring->btx_ring[position].buffer = buffer_ma; - blk_ring->btx_ring[position].block_number = block_number; - blk_ring->btx_ring[position].block_size = block_size; - blk_ring->btx_ring[position].device = phys_device; - blk_ring->btx_ring[position].sector_number = sector_number; - - blk_ring->btx_prod = BLK_TX_RING_INC(blk_ring->btx_prod); + position = blk_ring->req_prod; + blk_ring->req_ring[position].id = id; + blk_ring->req_ring[position].priority = mode; + blk_ring->req_ring[position].operation = operation; + blk_ring->req_ring[position].buffer = buffer_ma; + blk_ring->req_ring[position].block_number = block_number; + blk_ring->req_ring[position].block_size = block_size; + blk_ring->req_ring[position].device = phys_device; + blk_ring->req_ring[position].sector_number = sector_number; + + blk_ring->req_prod = BLK_REQ_RING_INC(blk_ring->req_prod); switch(mode) { @@ -325,20 +325,16 @@ static void do_xlblk_request (request_queue_t *rq) /* is there space in the tx ring for this request? * if the ring is full, then leave the request in the queue * - * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING BTX_CONS + * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING REQ_CONS * AT THE SAME TIME */ - { - blk_ring_t *blk_ring = start_info.blk_ring; - - if (BLK_RX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons) - { - printk (KERN_ALERT "OOPS, TX LOOKS FULL cons: %d prod: %d\n", - blk_ring->btx_cons, blk_ring->btx_prod); - BUG(); - break; - } - } + if (BLK_RESP_RING_INC(blk_ring->req_prod) == blk_ring->req_cons) + { + printk (KERN_ALERT "OOPS, TX LOOKS FULL cons: %d prod: %d\n", + blk_ring->req_cons, blk_ring->req_prod); + BUG(); + break; + } req->errors = 0; blkdev_dequeue_request(req); @@ -382,24 +378,22 @@ static struct block_device_operations xenolinux_block_fops = revalidate: xenolinux_block_revalidate, }; -static void xlblk_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) +static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs) { - blk_ring_t *blk_ring = start_info.blk_ring; struct request *req; int loop; u_long flags; - for (loop = blk_ring->brx_cons; - loop != blk_ring->brx_prod; - loop = BLK_RX_RING_INC(loop)) { + for (loop = blk_ring->resp_cons; + loop != blk_ring->resp_prod; + loop = BLK_RESP_RING_INC(loop)) { - blk_ring_entry_t *bret = &blk_ring->brx_ring[loop]; + blk_ring_resp_entry_t *bret = &blk_ring->resp_ring[loop]; - if(bret->operation == XEN_BLOCK_PROBE) - continue; + req = (struct request *)bret->id; + if ( req == NULL ) continue; /* probes have NULL id */ spin_lock_irqsave(&io_request_lock, flags); - req = (struct request *)bret->id; if (!end_that_request_first(req, 1, "XenBlk")) end_that_request_last(req); @@ -407,54 +401,27 @@ static void xlblk_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) } - blk_ring->brx_cons = loop; + blk_ring->resp_cons = loop; } -static void xlblk_tx_int(int irq, void *dev_id, struct pt_regs *ptregs) -{ - if (XLBLK_DEBUG) - printk (KERN_ALERT "--- xlblock::xlblk_tx_int\n"); -} int __init xlblk_init(void) { - blk_ring_t *blk_ring = start_info.blk_ring; int loop, error, result; - /* initialize memory rings to communicate with hypervisor */ - if ( blk_ring == NULL ) return -ENOMEM; + /* This mapping was created early at boot time. */ + blk_ring = (blk_ring_t *)FIX_BLKRING_BASE; - blk_ring->btx_prod = blk_ring->btx_cons = 0; - blk_ring->brx_prod = blk_ring->brx_cons = 0; - blk_ring->btx_ring = NULL; - blk_ring->brx_ring = NULL; - - blk_ring->btx_ring = kmalloc(BLK_TX_RING_SIZE * sizeof(blk_ring_entry_t), - GFP_KERNEL); - blk_ring->brx_ring = kmalloc(BLK_RX_RING_SIZE * sizeof(blk_ring_entry_t), - GFP_KERNEL); - - if ((blk_ring->btx_ring == NULL) || (blk_ring->brx_ring == NULL)) { - printk (KERN_ALERT "could not alloc ring memory for block device\n"); - error = -ENOBUFS; - goto fail; - } + blk_ring->req_prod = blk_ring->req_cons = 0; + blk_ring->resp_prod = blk_ring->resp_cons = 0; - error = request_irq(XLBLK_RX_IRQ, xlblk_rx_int, 0, - "xlblk-rx", &xlblk_device); + error = request_irq(XLBLK_RESPONSE_IRQ, xlblk_response_int, 0, + "xlblk-response", &xlblk_device); if (error) { printk(KERN_ALERT "Could not allocate receive interrupt\n"); goto fail; } - error = request_irq(XLBLK_TX_IRQ, xlblk_tx_int, 0, - "xlblk-tx", &xlblk_device); - if (error) { - printk(KERN_ALERT "Could not allocate transmit interrupt\n"); - free_irq(XLBLK_RX_IRQ, &xlblk_device); - goto fail; - } - memset (&xen_disk_info, 0, sizeof(xen_disk_info)); xen_disk_info.count = 0; @@ -505,8 +472,6 @@ int __init xlblk_init(void) return 0; fail: - if (blk_ring->btx_ring) kfree(blk_ring->btx_ring); - if (blk_ring->brx_ring) kfree(blk_ring->brx_ring); return error; } diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block_test.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block_test.c index cab6d9a330..4d09a10409 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block_test.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block_test.c @@ -22,7 +22,7 @@ /******************************************************************/ static struct proc_dir_entry *bdt; -static blk_ring_entry_t meta; +static blk_ring_req_entry_t meta; static char * data; static int proc_read_bdt(char *page, char **start, off_t off, diff --git a/xenolinux-2.4.16-sparse/arch/xeno/mm/init.c b/xenolinux-2.4.16-sparse/arch/xeno/mm/init.c index b1e75a6bcf..ac2019910e 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/mm/init.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/mm/init.c @@ -115,7 +115,9 @@ static inline void set_pte_phys (unsigned long vaddr, if (pte_val(*pte)) pte_ERROR(*pte); pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags); - set_pte(pte, mk_pte_phys(phys, prot)); + + /* We queue directly, avoiding hidden phys->machine translation. */ + queue_l1_entry_update(__pa(pte), phys | pgprot_val(prot)); /* * It's enough to flush this one mapping. @@ -124,10 +126,54 @@ static inline void set_pte_phys (unsigned long vaddr, __flush_tlb_one(vaddr); } +void __set_fixmap (enum fixed_addresses idx, unsigned long phys, + pgprot_t flags) +{ + unsigned long address = __fix_to_virt(idx); + + if (idx >= __end_of_fixed_addresses) { + printk("Invalid __set_fixmap\n"); + return; + } + set_pte_phys(address, phys, flags); +} + +static void __init fixrange_init (unsigned long start, + unsigned long end, pgd_t *pgd_base) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int i, j; + unsigned long vaddr; + + vaddr = start; + i = __pgd_offset(vaddr); + j = __pmd_offset(vaddr); + pgd = pgd_base + i; + + for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { + pmd = (pmd_t *)pgd; + for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { + if (pmd_none(*pmd)) { + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); + if (pte != pte_offset(pmd, 0)) + BUG(); + } + vaddr += PMD_SIZE; + } + j = 0; + } + + XENO_flush_page_update_queue(); +} + void __init paging_init(void) { unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; unsigned int max_dma, high, low; + unsigned long vaddr; max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; @@ -143,6 +189,19 @@ void __init paging_init(void) zones_size[ZONE_NORMAL] = low - max_dma; } free_area_init(zones_size); + + /* + * Fixed mappings, only the page table structure has to be created - + * mappings will be set by set_fixmap(): + */ + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + fixrange_init(vaddr, 0, init_mm.pgd); + + /* + * XXX We do this conversion early, so that all other page tables + * will automatically get this mapping. + */ + set_fixmap(FIX_BLKRING_BASE, start_info.blk_ring); } diff --git a/xenolinux-2.4.16-sparse/include/asm-xeno/pgtable.h b/xenolinux-2.4.16-sparse/include/asm-xeno/pgtable.h index 30764d7b75..5c3d46e36b 100644 --- a/xenolinux-2.4.16-sparse/include/asm-xeno/pgtable.h +++ b/xenolinux-2.4.16-sparse/include/asm-xeno/pgtable.h @@ -18,6 +18,7 @@ #include #include #include +#include #ifndef _I386_BITOPS_H #include @@ -99,7 +100,7 @@ extern void pgtable_cache_init(void); #define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \ ~(VMALLOC_OFFSET-1)) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END (HYPERVISOR_VIRT_START-PAGE_SIZE) +#define VMALLOC_END (FIXADDR_START - 2*PAGE_SIZE) #define _PAGE_BIT_PRESENT 0 #define _PAGE_BIT_RW 1 -- 2.30.2